﻿namespace NTLib.Core.Collection
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;

    /// <summary>
    /// 
    /// </summary>
    public static class StackExtensions
    {
        #region Methods

        /// <summary>
        /// Extracts the specified item from the stack.
        /// Recursive algorithme
        /// </summary>
        /// <typeparam name="TItem">The type of the item.</typeparam>
        /// <param name="th">The th.</param>
        /// <param name="item">The item.</param>
        public static void Extract<TItem>(this Stack<TItem> th, TItem item)
        {
            if (!th.Contains(item))
                return;
            ExtractRec(th, item);
        }

        /// <summary>
        /// Extracts the specified predicate.
        /// </summary>
        /// <typeparam name="TItem">The type of the item.</typeparam>
        /// <param name="th">The th.</param>
        /// <param name="predicate">The predicate.</param>
        public static void Extract<TItem>(this Stack<TItem> th, Func<TItem, bool> predicate)
        {
            var item = th.FirstOrDefault(predicate);
            if (item != null)
                ExtractRec(th, item);
            return;
        }

        /// <summary>
        /// Extracts the record.
        /// </summary>
        /// <typeparam name="TItem">The type of the item.</typeparam>
        /// <param name="stack">The stack.</param>
        /// <param name="item">The item.</param>
        private static void ExtractRec<TItem>(Stack<TItem> stack, TItem item)
        {
            var popItem = stack.Pop();
            if (EqualityComparer<TItem>.Default.Equals(popItem, item))
                return;
            ExtractRec(stack, item);
            stack.Push(popItem);
        }

        #endregion
    }
}
